﻿
namespace VMWareLabWorkflowsDataContracts.VMWareLabDetailsDialogControls.Commands
{
    using System;
    using System.IO;
    using System.Reflection;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;

    /// <summary>
    /// Creates a deep copy of the object
    /// </summary>
    public static class ObjectCloner
    {
        public static T Clone<T>(T source)
        {
            if (!typeof(T).IsSerializable)
            {
                throw new ArgumentException("The type must be serializable.", "source");
            }

            if (ReferenceEquals(source, null))
            {
                return default(T);
            }

            IFormatter formatter = new BinaryFormatter();
            Stream stream = new MemoryStream();
            using (stream)
            {
                formatter.Serialize(stream, source);
                formatter.Binder = new ThisAssemblyDeserializationBinder();
                stream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(stream);
            }
        }
    }

    sealed class ThisAssemblyDeserializationBinder : SerializationBinder
    {
        public override Type BindToType(string assemblyName, string typeName)
        {
            string temp = assemblyName;
            Type typeToDeserialize = null;
            string currentAssembly = Assembly.GetExecutingAssembly().FullName;
            assemblyName = currentAssembly;
            typeToDeserialize = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));
           
            if (typeToDeserialize == null)
            {
                typeToDeserialize =
                Type.GetType(String.Format("{0}, {1}", typeName, temp));
            }
            return typeToDeserialize;
        }
    }
}
